#pragma once
#include <string>
#include <jsoncpp/json/json.h>

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";



struct CustomProtoco
{
    static std::string Encode(const std::string& content)
    {
        size_t len = content.size();
        std::string text = std::to_string(len);
        text += protocol_sep;
        text += content;
        text += protocol_sep;
        return text;
    }

    static bool Decode(std::string& text, std::string& content)
    {
        size_t pos = text.find(protocol_sep);
        if(pos == std::string::npos)    
            return false;

        std::string size_str = text.substr(0, pos);
        int size = stoi(size_str);

        // int pos2 = text.find(protocol_sep, pos + 1);
        // if(pos2 == std::string::npos || pos2 - pos != size + 1);
        //     return false;

        size_t total_len = size_str.size() + size + 2;
        if(text.size() < total_len)
            return false;

        content = text.substr(pos + 1, size);
        text.erase(0, total_len);
        return true;
    }
};


class Request
{
public:
    Request(int x, int y, char op) :_x(x), _y(y), _op(op) {};
    Request() = default;

    //序列化  size\nx + y\n
    std::string serialize()
    {
#ifdef MY
        std::string content = std::to_string(_x);
        content += blank_space_sep;
        content += _op;
        content += blank_space_sep;
        content += std::to_string(_y);
        return content;
#else
        std::string content;
        Json::Value root;
        root["_x"] = _x;
        root["_y"] = _y;
        root["_op"] = _op;
        Json::StyledWriter w;
        content = w.write(root);
        return content;
#endif
    }

    //反序列化
    bool deserialize(std::string& content)
    {
#ifdef MY
        size_t pos1 = content.find(blank_space_sep);
        if(std::string::npos == pos1)
            return false;

        size_t pos2 = content.rfind(blank_space_sep);
        if(std::string::npos == pos2 || pos2 - pos1 != 2)
            return false;
        
        _x = stoi(content.substr(0, pos1));
        _y = stoi(content.substr(pos2 + 1));
        _op = content[pos1 + 1];
#else
        Json::Reader r;
        Json::Value root;
        r.parse(content, root);

        _x = root["_x"].asInt();
        _y = root["_y"].asInt();
        _op = root["_op"].asInt();
#endif
        
        return true;
    }

public:
    int _x;
    int _y;
    char _op;
};


class Response
{
public:
    //序列化  size\answer code\n
    std::string serialize()
    {
#ifdef MY
        std::string content = std::to_string(_answer);
        content += blank_space_sep;
        content += std::to_string(_code);
        return content;
#else
        std::string content;
        Json::Value root;
        root["_answer"] = _answer;
        root["_code"] = _code;
        Json::StyledWriter w;
        content = w.write(root);
        return content;
#endif
    }

    bool deserialize(std::string& content)                        
    {
#ifdef MY
        size_t pos = content.find(blank_space_sep);
        if(std::string::npos == pos)
            return false;

        _answer = stoi(content.substr(0, pos));
        _code = stoi(content.substr(pos + 1));
#else
        Json::Value root;
        Json::Reader r;
        r.parse(content, root);
        _answer = root["_answer"].asInt();
        _code = root["_cose"].asInt();
#endif
        return true;
    }

public:
    int _answer= 0;
    int _code = 0;
};